// PWA utilities for service worker and push notifications

export class PWAManager {
  private static instance: PWAManager;
  private serviceWorkerRegistration: ServiceWorkerRegistration | null = null;

  private constructor() {}

  static getInstance(): PWAManager {
    if (!PWAManager.instance) {
      PWAManager.instance = new PWAManager();
    }
    return PWAManager.instance;
  }

  // Register service worker
  async registerServiceWorker(): Promise<boolean> {
    if ('serviceWorker' in navigator) {
      try {
        const registration = await navigator.serviceWorker.register('/sw.js');
        this.serviceWorkerRegistration = registration;
        
        console.log('Service Worker registered successfully:', registration);
        
        // Check for updates
        registration.addEventListener('updatefound', () => {
          const newWorker = registration.installing;
          if (newWorker) {
            newWorker.addEventListener('statechange', () => {
              if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
                // New service worker installed, show update notification
                this.showUpdateNotification();
              }
            });
          }
        });

        return true;
      } catch (error) {
        console.error('Service Worker registration failed:', error);
        return false;
      }
    }
    return false;
  }

  // Request notification permission (must be called from user gesture)
  async requestNotificationPermission(): Promise<NotificationPermission> {
    if ('Notification' in window) {
      try {
        const permission = await Notification.requestPermission();
        console.log('Notification permission:', permission);
        return permission;
      } catch (error) {
        console.error('Failed to request notification permission:', error);
        return 'denied';
      }
    }
    return 'denied';
  }

  // Enable notifications with user interaction
  async enableNotifications(): Promise<boolean> {
    const permission = await this.requestNotificationPermission();
    if (permission === 'granted') {
      // 可以选择性订阅推送通知
      await this.subscribeToPushNotifications();
      return true;
    }
    return false;
  }

  // Subscribe to push notifications
  async subscribeToPushNotifications(): Promise<PushSubscription | null> {
    if (!this.serviceWorkerRegistration) {
      console.error('Service Worker not registered');
      return null;
    }

    try {
      const subscription = await this.serviceWorkerRegistration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: this.urlBase64ToUint8Array(
          // Replace with your VAPID public key
          'YOUR_VAPID_PUBLIC_KEY_HERE'
        )
      });

      console.log('Push subscription:', subscription);
      
      // Send subscription to server
      await this.sendSubscriptionToServer(subscription);
      
      return subscription;
    } catch (error) {
      console.error('Failed to subscribe to push notifications:', error);
      return null;
    }
  }

  // Show local notification
  showNotification(title: string, options?: NotificationOptions): void {
    if ('Notification' in window && Notification.permission === 'granted') {
      new Notification(title, {
        icon: '/icons/icon-192x192.png',
        badge: '/icons/badge-72x72.png',
        ...options
      });
    }
  }

  // Check if app can be installed
  canInstall(): boolean {
    return 'beforeinstallprompt' in window;
  }

  // Prompt user to install app
  async promptInstall(): Promise<boolean> {
    const event = (window as any).deferredPrompt;
    if (event) {
      event.prompt();
      const result = await event.userChoice;
      console.log('Install prompt result:', result);
      return result.outcome === 'accepted';
    }
    return false;
  }

  // Check if app is in standalone mode
  isStandalone(): boolean {
    return window.matchMedia('(display-mode: standalone)').matches ||
           (window.navigator as any).standalone === true;
  }

  // Check if device is online
  isOnline(): boolean {
    return navigator.onLine;
  }

  // Add network status listeners
  addNetworkListeners(
    onOnline: () => void,
    onOffline: () => void
  ): () => void {
    window.addEventListener('online', onOnline);
    window.addEventListener('offline', onOffline);

    // Return cleanup function
    return () => {
      window.removeEventListener('online', onOnline);
      window.removeEventListener('offline', onOffline);
    };
  }

  // Show update notification
  private showUpdateNotification(): void {
    this.showNotification('应用更新', {
      body: '新版本已准备就绪，请刷新页面获取最新功能',
      tag: 'app-update',
      requireInteraction: true
    });
  }

  // Convert VAPID key
  private urlBase64ToUint8Array(base64String: string): Uint8Array {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
      .replace(/-/g, '+')
      .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
      outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
  }

  // Send subscription to server
  private async sendSubscriptionToServer(subscription: PushSubscription): Promise<void> {
    try {
      const response = await fetch('/api/v1/push/subscribe', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(subscription)
      });

      if (!response.ok) {
        throw new Error('Failed to send subscription to server');
      }
    } catch (error) {
      console.error('Error sending subscription to server:', error);
    }
  }
}

// Initialize PWA features
export const initializePWA = async (): Promise<void> => {
  const pwaManager = PWAManager.getInstance();
  
  // Register service worker
  await pwaManager.registerServiceWorker();
  
  // 不自动请求通知权限，等待用户手动触发
  // await pwaManager.requestNotificationPermission();
  
  // Handle install prompt
  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault();
    (window as any).deferredPrompt = e;
  });
  
  // Handle app installed
  window.addEventListener('appinstalled', () => {
    console.log('App installed successfully');
    // 只在用户同意后显示通知
    if (Notification.permission === 'granted') {
      pwaManager.showNotification('安装成功', {
        body: 'FastAPI Platform 已成功安装到您的设备',
        tag: 'app-installed'
      });
    }
  });
};

export default PWAManager;